#include "ExtensionsLoader.hpp"


//! Setting values for static variables.
//! Functions for shaders.
PFNGLCREATEPROGRAMOBJECTARBPROC  ExtensionsLoader::glCreateProgramObjectARB  = 0;
PFNGLDELETEOBJECTARBPROC         ExtensionsLoader::glDeleteObjectARB         = 0;
PFNGLUSEPROGRAMOBJECTARBPROC     ExtensionsLoader::glUseProgramObjectARB     = 0;
PFNGLCREATESHADEROBJECTARBPROC   ExtensionsLoader::glCreateShaderObjectARB   = 0;
PFNGLSHADERSOURCEARBPROC         ExtensionsLoader::glShaderSourceARB         = 0;
PFNGLCOMPILESHADERARBPROC        ExtensionsLoader::glCompileShaderARB        = 0;
PFNGLGETOBJECTPARAMETERIVARBPROC ExtensionsLoader::glGetObjectParameterivARB = 0;
PFNGLATTACHOBJECTARBPROC         ExtensionsLoader::glAttachObjectARB         = 0;
PFNGLGETINFOLOGARBPROC           ExtensionsLoader::glGetInfoLogARB           = 0;
PFNGLLINKPROGRAMARBPROC          ExtensionsLoader::glLinkProgramARB          = 0;
PFNGLGETUNIFORMLOCATIONARBPROC   ExtensionsLoader::glGetUniformLocationARB   = 0;
PFNGLUNIFORM4FARBPROC            ExtensionsLoader::glUniform4fARB            = 0;
PFNGLUNIFORM1IARBPROC            ExtensionsLoader::glUniform1iARB            = 0;
PFNGLUNIFORM1FARBPROC            ExtensionsLoader::glUniform1fARB            = 0;
PFNGLUNIFORMMATRIX4FVARBPROC     ExtensionsLoader::glUniformMatrix4fvARB     = 0;
PFNGLUNIFORM4FVARBPROC           ExtensionsLoader::glUniform4fvARB           = 0;
PFNGLUNIFORM3FVARBPROC           ExtensionsLoader::glUniform3fvARB           = 0;
PFNGLGETPROGRAMIVARBPROC         ExtensionsLoader::glGetProgramivARB         = 0;

//! Functions for frame buffer object.
PFNGLGENFRAMEBUFFERSEXTPROC                      ExtensionsLoader::glGenFramebuffersEXT                      = 0;
PFNGLGENRENDERBUFFERSEXTPROC                     ExtensionsLoader::glGenRenderbuffersEXT                     = 0;
PFNGLBINDFRAMEBUFFEREXTPROC                      ExtensionsLoader::glBindFramebufferEXT                      = 0;
PFNGLBINDRENDERBUFFEREXTPROC                     ExtensionsLoader::glBindRenderbufferEXT                     = 0;
PFNGLISRENDERBUFFEREXTPROC                       ExtensionsLoader::glIsRenderbufferEXT                       = 0;
PFNGLISFRAMEBUFFEREXTPROC                        ExtensionsLoader::glIsFramebufferEXT                        = 0;
PFNGLDELETERENDERBUFFERSEXTPROC                  ExtensionsLoader::glDeleteRenderbuffersEXT                  = 0;
PFNGLDELETEFRAMEBUFFERSEXTPROC                   ExtensionsLoader::glDeleteFramebuffersEXT                   = 0;
PFNGLRENDERBUFFERSTORAGEEXTPROC                  ExtensionsLoader::glRenderbufferStorageEXT                  = 0;
PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC           ExtensionsLoader::glGetRenderbufferParameterivEXT           = 0;
PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC               ExtensionsLoader::glCheckFramebufferStatusEXT               = 0;
PFNGLFRAMEBUFFERTEXTURE1DEXTPROC                 ExtensionsLoader::glFramebufferTexture1DEXT                 = 0;
PFNGLFRAMEBUFFERTEXTURE2DEXTPROC                 ExtensionsLoader::glFramebufferTexture2DEXT                 = 0;
PFNGLFRAMEBUFFERTEXTURE3DEXTPROC                 ExtensionsLoader::glFramebufferTexture3DEXT                 = 0;
PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC              ExtensionsLoader::glFramebufferRenderbufferEXT              = 0;
PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC  ExtensionsLoader::glGetFramebufferAttachmentParameterivEXT  = 0;
PFNGLGENERATEMIPMAPEXTPROC                       ExtensionsLoader::glGenerateMipmapEXT                       = 0;

//! ExtensionsLoader instance.
ExtensionsLoader*                ExtensionsLoader::m_instance                = 0;

//! GetInstance method returns pointer to ExtensionsLoader instance
//! and ensures that only one such instance exists.
ExtensionsLoader* ExtensionsLoader::GetInstance()
{
	if( !m_instance )
	{
		m_instance = new ExtensionsLoader;
	}

	return m_instance;
}

//! Private ExtensionsLoader constructor called on first use of 
//! ExtensionsLoader::GetInstance() method. Here the pointers 
//! to ARB functions are being set.
ExtensionsLoader::ExtensionsLoader()
{
	//! Mounting extensions
	glCreateProgramObjectARB  = ( PFNGLCREATEPROGRAMOBJECTARBPROC )wglGetProcAddress( "glCreateProgramObjectARB" );
	glDeleteObjectARB         = ( PFNGLDELETEOBJECTARBPROC )wglGetProcAddress( "glDeleteObjectARB" );
	glUseProgramObjectARB     = ( PFNGLUSEPROGRAMOBJECTARBPROC )wglGetProcAddress( "glUseProgramObjectARB" );
	glCreateShaderObjectARB   = ( PFNGLCREATESHADEROBJECTARBPROC )wglGetProcAddress( "glCreateShaderObjectARB" );
	glShaderSourceARB         = ( PFNGLSHADERSOURCEARBPROC )wglGetProcAddress( "glShaderSourceARB" );
	glCompileShaderARB        = ( PFNGLCOMPILESHADERARBPROC )wglGetProcAddress( "glCompileShaderARB" );
	glGetObjectParameterivARB = ( PFNGLGETOBJECTPARAMETERIVARBPROC )wglGetProcAddress( "glGetObjectParameterivARB" );
	glAttachObjectARB         = ( PFNGLATTACHOBJECTARBPROC )wglGetProcAddress( "glAttachObjectARB" );
	glGetInfoLogARB           = ( PFNGLGETINFOLOGARBPROC )wglGetProcAddress( "glGetInfoLogARB" );
	glLinkProgramARB          = ( PFNGLLINKPROGRAMARBPROC )wglGetProcAddress( "glLinkProgramARB" );
	glGetUniformLocationARB   = ( PFNGLGETUNIFORMLOCATIONARBPROC )wglGetProcAddress( "glGetUniformLocationARB" );
	glUniform4fARB            = ( PFNGLUNIFORM4FARBPROC )wglGetProcAddress( "glUniform4fARB" );
	glUniform1iARB            = ( PFNGLUNIFORM1IARBPROC )wglGetProcAddress( "glUniform1iARB" );
	glUniform1fARB            = ( PFNGLUNIFORM1FARBPROC )wglGetProcAddress( "glUniform1fARB" );
	glUniform4fvARB           = ( PFNGLUNIFORM4FVARBPROC )wglGetProcAddress( "glUniform4fvARB" );
	glUniform3fvARB           = ( PFNGLUNIFORM3FVARBPROC )wglGetProcAddress( "glUniform3fvARB" );
	glUniformMatrix4fvARB     = ( PFNGLUNIFORMMATRIX4FVARBPROC )wglGetProcAddress( "glUniformMatrix4fvARB" );
	glGetProgramivARB		  = ( PFNGLGETPROGRAMIVARBPROC )wglGetProcAddress( "glGetProgramivARB" );

	glGenFramebuffersEXT                      = ( PFNGLGENFRAMEBUFFERSEXTPROC )wglGetProcAddress( "glGenFramebuffersEXT" );
	glGenRenderbuffersEXT                     = ( PFNGLGENRENDERBUFFERSEXTPROC )wglGetProcAddress( "glGenRenderbuffersEXT" );
	glBindFramebufferEXT                      = ( PFNGLBINDFRAMEBUFFEREXTPROC )wglGetProcAddress( "glBindFramebufferEXT" );
	glBindRenderbufferEXT                     = ( PFNGLBINDRENDERBUFFEREXTPROC )wglGetProcAddress( "glBindRenderbufferEXT" );
	glIsRenderbufferEXT                       = ( PFNGLISRENDERBUFFEREXTPROC )wglGetProcAddress( "glIsRenderbufferEXT" );
	glIsFramebufferEXT                        = ( PFNGLISFRAMEBUFFEREXTPROC )wglGetProcAddress( "glIsFramebufferEXT" );
	glDeleteRenderbuffersEXT                  = ( PFNGLDELETERENDERBUFFERSEXTPROC )wglGetProcAddress( "glDeleteRenderbuffersEXT" );
	glDeleteFramebuffersEXT                   = ( PFNGLDELETEFRAMEBUFFERSEXTPROC )wglGetProcAddress( "glDeleteFramebuffersEXT" );
	glRenderbufferStorageEXT                  = ( PFNGLRENDERBUFFERSTORAGEEXTPROC )wglGetProcAddress( "glRenderbufferStorageEXT" );
	glGetRenderbufferParameterivEXT           = ( PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC )wglGetProcAddress( "glGetRenderbufferParameterivEXT" );
	glCheckFramebufferStatusEXT               = ( PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC )wglGetProcAddress( "glCheckFramebufferStatusEXT" );
	glFramebufferTexture1DEXT                 = ( PFNGLFRAMEBUFFERTEXTURE1DEXTPROC )wglGetProcAddress( "glFramebufferTexture1DEXT" );
	glFramebufferTexture2DEXT                 = ( PFNGLFRAMEBUFFERTEXTURE2DEXTPROC )wglGetProcAddress( "glFramebufferTexture2DEXT" );
	glFramebufferTexture3DEXT                 = ( PFNGLFRAMEBUFFERTEXTURE3DEXTPROC )wglGetProcAddress( "glFramebufferTexture3DEXT" );
	glFramebufferRenderbufferEXT              = ( PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC )wglGetProcAddress( "glFramebufferRenderbufferEXT" );
	glGetFramebufferAttachmentParameterivEXT  = ( PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC )wglGetProcAddress( "glGetFramebufferAttachmentParameterivEXT" );
	glGenerateMipmapEXT                       = ( PFNGLGENERATEMIPMAPEXTPROC )wglGetProcAddress( "glGenerateMipmapEXT" );

}
